﻿using System;
using Utils.Extensions;
using Utils.Wpf;

namespace Plugins.UserControls
{
    public class HourSelectorVM : ViewModelValidatedBase
    {
        #region Attributes

        private DateTime? _operationStart;
        private DateTime? _lastOpen;
        private DateTime? _forcedCloseTime;

        #endregion

        #region Properties

        public HourSelectorData Data { get; private set; }

        public bool StartWithOpening
        {
            get
            {
                return this.Data.StartWithOpening;
            }
            set
            {
                if (this.Data.StartWithOpening != value)
                {
                    this.Data.StartWithOpening = value;
                    base.OnPropertyChanged("StartWithOpening");
                    base.OnPropertyChanged("OperationStart"); // To validate again
                }
            }
        }

        public DateTime? OperationStart
        {
            get
            {
				// Initialize operationStart when this.Data.StartDate has been init
				if (_operationStart == null && this.Data.OperationStart != null)
				{
					_operationStart = new DateTime(2000, 1, 1) + this.Data.OperationStart.Value;
				}

                return _operationStart;
            }
            set
            {
                if (_operationStart != value)
                {
                    if (value == null)
                    {
                        throw new ArgumentNullException("value", "Null can only be the initial value. You cannot set it to null");
                    }
                    _operationStart = value;
                    this.Data.OperationStart = _operationStart.Value.TimeOfDay;
                    base.OnPropertyChanged("OperationStart");
                }
            }
        }

        public DateTime? LastOpen
        {
            get
            {
            	return _lastOpen ?? (_lastOpen = new DateTime(2000, 1, 1) + this.Data.LastOpen);
            }
        	set
            {
                if (_lastOpen != value)
                {
                    if (value == null)
                    {
                        throw new ArgumentNullException("value", "Null can only be the initial value. You cannot set it to null");
                    }

                    _lastOpen = value;
                    this.Data.LastOpen = _lastOpen.Value.TimeOfDay;
                    base.OnPropertyChanged("LastOpen");
                    base.OnPropertyChanged("ForcedCloseTime"); // To force validation again
                }
            }
        }

        public DateTime? ForcedCloseTime
        {
            get
            {
            	return _forcedCloseTime ?? (_forcedCloseTime = new DateTime(2000, 1, 1) + this.Data.ForcedCloseTime);
            }
        	set
            {
                if (_forcedCloseTime != value)
                {
                    if (value == null)
                    {
                        throw new ArgumentNullException("value", "Null can only be the initial value. You cannot set it to null");
                    }

                    _forcedCloseTime = value; 
                    this.Data.ForcedCloseTime = _forcedCloseTime.Value.TimeOfDay;
                    base.OnPropertyChanged("LastOpen"); // To force validation again
                    base.OnPropertyChanged("ForcedCloseTime"); 
                }
            }
        }

        #endregion

        #region Public Methods

        public HourSelectorVM()
        {
			this.Data = new HourSelectorData();
			this.Data.PropertyChanged += this.Data_PropertyChanged; // Local object
        }

        protected override string ValidateField(string fieldName)
        {
            string result = null;

            if (fieldName == "OperationStart")
            {
                if (!this.StartWithOpening && this.OperationStart == null)
                {
                    base.ValidatedErrors[fieldName] = true;
                    result = "The operation start time cannot be null";
                }
            }
            else if (fieldName == "LastOpen")
            {
                if (this.LastOpen == null)
                {
                    base.ValidatedErrors[fieldName] = true;
                    result = "The last open time cannot be null";
                }
                else if (this.ForcedCloseTime != null && this.ForcedCloseTime.Value < this.LastOpen.Value)
                {
                    base.ValidatedErrors[fieldName] = true;
                    result = "The last open time cannot be greater than the last open time";
                }
            }
            else if (fieldName == "ForcedCloseTime")
            {
                if (this.ForcedCloseTime == null)
                {
                    base.ValidatedErrors[fieldName] = true;
                    result = "The forced closed time cannot be null";
                }
                else if (this.LastOpen != null && this.ForcedCloseTime.Value < this.LastOpen.Value)
                {
                    base.ValidatedErrors[fieldName] = true;
                    result = "The forced closed time cannot be smaller than the last open time";
                }
            }

            return result;
        }

        #endregion

		#region Event Handlers

		private void Data_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
		{
			if (e.PropertyName == "OperationStart" && _operationStart != null && this.Data.OperationStart != null)
			{
				_operationStart = _operationStart.Value.ChangeTime(this.Data.OperationStart.Value);
				base.OnPropertyChanged("OperationStart"); 
			}
			else if (e.PropertyName == "LastOpen" && _lastOpen != null)
			{
				_lastOpen = _lastOpen.Value.ChangeTime(this.Data.LastOpen);
				base.OnPropertyChanged("ForcedCloseTime"); // To force validation again
				base.OnPropertyChanged("LastOpen"); 
			}
			else if (e.PropertyName == "ForcedCloseTime" && _forcedCloseTime != null)
			{
				_forcedCloseTime = _forcedCloseTime.Value.ChangeTime(this.Data.ForcedCloseTime);
				base.OnPropertyChanged("ForcedCloseTime"); 
				base.OnPropertyChanged("LastOpen"); // To force validation again
			}
			else
			{
				base.OnPropertyChanged(e.PropertyName);	
			}
			
		}

		#endregion

    }
}
